/***************************************************
> Copyright (C) 2024 ==KINGYI== All rights reserved.
> File Name: 3.c
> Author:
> Mail: 
> Created Time: 2024年11月28日 星期四 11时08分02秒
***************************************************/

#include "server.h"
#include "cJSON.h"

#define PORT "8888" 
#define IP "192.168.0.193" 


int server(void)
{
	mysql = db_init(mysql);  //数据连接成功的判断
	//创建套接字,监听套接字
	int server_socket = socket(AF_INET,SOCK_STREAM,0);

	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(atoi(PORT));
	saddr.sin_addr.s_addr = inet_addr(IP);

	int optval = 1;
	//bind 的地址允许重复使用
	setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));
	int isbind = bind(server_socket,(struct sockaddr*)&saddr,sizeof(saddr));
	if(isbind == -1)
	{
		perror("bind");
		return -1;
	}

	//启动监听
	int islisten = listen(server_socket,10);
	if(islisten == -1)
	{
		perror("listen");
		return -1;
	}
	printf("监听已启动\n");

	int epfd = epoll_create(1);
	struct epoll_event ev;
	ev.events = EPOLLIN ;
	ev.data.fd = server_socket;

	int ret = epoll_ctl(epfd,EPOLL_CTL_ADD,server_socket,&ev);
	if(ret == -1)
	{
		perror("epoll_ctl");
		return -1;
	}
	struct sockaddr_in caddr;
	int addrlen = sizeof(caddr);
	char buf[6] = {0};
	struct epoll_event events[40];
	while(1)
	{
		int num = epoll_wait(epfd,events,40,5000);
		for(int i=0;i<num;i++)
		{
			int fd = events[i].data.fd;
			if(fd == server_socket)
			{
				int client_socket = accept(server_socket,(struct sockaddr*)&caddr,&addrlen);
				printf("ip:%s,port:%d\n",inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));
				ev.events = EPOLLIN | EPOLLET;
				ev.data.fd = client_socket;
				epoll_ctl(epfd,EPOLL_CTL_ADD,client_socket,&ev);
			}
			int flag = fcntl(fd,F_GETFL);
			flag |= O_NONBLOCK;
			fcntl(fd,F_SETFL,flag);
			ClientType ct;
			ct.epfd = epfd;
			ct.fd = fd;
			pthread_t tid;
			pthread_create(&tid,NULL,read_msg,(void*)&ct);
			pthread_detach(tid);
		}
	}
	close(server_socket);
    return 0;
}

//数据库初始化
MYSQL db_init(MYSQL mysql)
{
	MYSQL *flag = NULL;
	
	mysql_init(&mysql);
	flag = mysql_real_connect(&mysql,"localhost","root","858935905ywh","class20DB",0,NULL,0);
	if(flag == NULL)
	{
		printf("connect mysql error:%s\n", mysql_error(&mysql));
		exit(1);
	}
	return mysql;
}

//添加信息到数据库
int insert_info(USER *user, MYSQL mysql)
{
	char bufsql[1000] = {0};
	sprintf(bufsql,"insert into user (name,pwd) values('%s','%s')", user->name,user->pwd);
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		exit(1);
	}
	memset(bufsql, 0, sizeof(bufsql));
	return 0;
}

//解包
char *parseJson(const char* p)
{
	USER *user;
	user = (USER*)malloc(sizeof(USER));
	memset(user,0,sizeof(USER));
	char ac[1024] = {0};
	char *pa = NULL;
	srand(time(NULL));
	cJSON* root = cJSON_Parse(p);

	cJSON* action = cJSON_GetObjectItem(root,"action");
	strcpy(ac ,cJSON_GetStringValue(action));

	if(strcmp(ac,"register")==0)
	{	
		cJSON* name = cJSON_GetObjectItem(root,"name");
		cJSON* passwd = cJSON_GetObjectItem(root,"pwd");
		strcpy(user->name, cJSON_GetStringValue(name));
		strcpy(user->pwd ,cJSON_GetStringValue(passwd));
		printf("name:%s,pwd:%s\n",user->name,user->pwd);

		if(insert_info(user,mysql) == 0)
		{
			pa = packJson(0);
		}
		else
		{
			pa = packJson(1);
		}
	}
	else if(strcmp(ac,"login")==0)
	{
		cJSON* name = cJSON_GetObjectItem(root,"name");
		cJSON* passwd = cJSON_GetObjectItem(root,"pwd");
		strcpy(user->name, cJSON_GetStringValue(name));
		strcpy(user->pwd ,cJSON_GetStringValue(passwd));
		printf("name:%s,pwd:%s\n",user->name,user->pwd);

		if(select_user(user, mysql) == 0)
		{
			pa = packJson(0);
		}
		else
		{
			pa = packJson(1);
		}
	}
	else if(strcmp(ac,"battery_status") == 0)
	{
		pa = packJson(rand()%3+1);
		printf("%s\n",pa);
	}
	else if(strcmp(ac,"battery_storage") == 0)
	{
		pa = packJson(rand()%3+1);
	}
	else if(strcmp(ac,"environment_monitor") == 0)
	{
		pa = packJson_envir(rand()%3+1);	
	}
	//else if(strcmp(ac,"history_records") == 0)


	return pa;
}

char *packJson(int num)	
{
	printf("1\n");
	char *p = (char*)malloc(1024);
	cJSON* root = cJSON_CreateObject();
	printf("2\n");
	cJSON* number = cJSON_CreateNumber(num);
	printf("3\n");
	cJSON_AddItemToObject(root,"returncode",number);
	strcpy(p,cJSON_Print(root));
	cJSON_Delete(root);	
	return p;
}

char *packJson_envir(int num)	
{
	char * p = (char*)malloc(1024);
	int res = rand()%100;
	cJSON* root = cJSON_CreateObject();
	cJSON* number = cJSON_CreateNumber(num);
	cJSON* temp = cJSON_CreateNumber(res);
	cJSON_AddItemToObject(root,"returncode",number);
	cJSON_AddItemToObject(root,"temp",temp);
	strcpy(p,cJSON_Print(root));
	cJSON_Delete(root);	
	return p;
}

void* read_msg(void* arg)
{
	ClientType ct = *(ClientType*)arg;
	char buf[1024]={0};
	char *p;
	struct epoll_event ev;
	ev.events = EPOLLIN | EPOLLET;
	ev.data.fd = ct.fd;
	while(1)
	{
		memset(buf,0,sizeof(buf));
		int size = read(ct.fd,buf,1023);

		if(size == -1)
		{
			break;
		}
		//断开连接
		if(size == 0)
		{
			epoll_ctl(ct.epfd,EPOLL_CTL_DEL,ct.fd,&ev);
			close(ct.fd);
		}
		if(size > 0)
		{
			printf("buf:%s\n",buf);
			//解包
			p =	parseJson(buf);
			write(ct.fd,p,strlen(p));
		}
	}
}

int select_user(USER *user,MYSQL mysql)
{
	MYSQL_RES *res = NULL;
    MYSQL_ROW row;
    MYSQL_FIELD *field = NULL;
    int i = 0;
    int j = 0;
	int index = 1;	
	
	//读取数据库的数据
	//数据库查询
    char bufsql[1000] = {0};
    strcpy(bufsql,"select name,pwd from user");
    //执行sql
    if(mysql_query(&mysql,bufsql)!=0)
    {
        printf("%s\n",mysql_error(&mysql));
        index = -1;
    }	
	
	//显示查询结果
    //获得结果集
    res = mysql_store_result(&mysql);
    //结果集的字段信息
    field = mysql_fetch_fields(res);
    //遍历行/记录 
    my_ulonglong Row = mysql_num_rows(res);
	if(Row<1)
	{
		index = -1;
	}

    //遍历列/字段个数
    int col = mysql_num_fields(res);
	// 打印表头
    for(i = 0;i<col;i++)
    {
        printf("| %2s ",field[i].name);
    }
    printf("|\n");
   
    for(i = 0;i<Row;i++)
    {
        row = mysql_fetch_row(res);
		
		if(strcmp(user->name,row[0])==0 &&strcmp(user->pwd,row[1])==0)
		{
			index = 0;
		}
        // 打印分隔线
        for(j = 0;j<col;j++)
        {
            printf("|  %2s   ", row[j]);
        }
        printf("|\n");
        printf("+-------+-------+-------+-------+\n");
    }
	
	return index;
}
